﻿@page "/Account/Manage/SetPassword"

@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Identity
@using MyApp.Data
@using MyApp.Identity

@inject UserManager<ApplicationUser> UserManager
@inject SignInManager<ApplicationUser> SignInManager
@inject UserAccessor UserAccessor
@inject IdentityRedirectManager RedirectManager

<PageTitle>Set password</PageTitle>

<Heading3>Set your password</Heading3>

<div class="max-w-xl">
    <StatusMessage class="mb-3" Message="@_message" />

    <p class="text-info">
        You do not have a local username/password for this site. Add a local
        account so you can log in without an external login.
    </p>

    <div class="mt-3 shadow overflow-hidden sm:rounded-md">
        <div class="px-4 bg-white dark:bg-black sm:p-6">
            <EditForm id="set-password-form" Model="Input" FormName="set-password" OnValidSubmit="OnValidSubmitAsync" method="post">
                <DataAnnotationsValidator />
                <ValidationSummary class="mb-3 text-danger text-center font-semibold" />

                <div class="flex flex-col gap-4">
                    <div>
                        <label for="new-password" class="@TextInput.LabelClasses">New password</label>
                        <div class="mt-1 relative rounded-md shadow-sm">
                            <InputText id="new-password" type="password" @bind-Value="Input.NewPassword" class="@TextInput.InputClasses" autocomplete="new-password" placeholder="Please enter your new password." />
                        </div>
                        <ValidationMessage For="() => Input.NewPassword" class="mt-2 text-danger text-sm" />
                    </div>
                    <div>
                        <label for="confirm-password" class="@TextInput.LabelClasses">Confirm password</label>
                        <div class="mt-1 relative rounded-md shadow-sm">
                            <InputText id="confirm-password" type="password" @bind-Value="Input.ConfirmPassword" class="@TextInput.InputClasses" autocomplete="new-password" placeholder="Please confirm your new password." />
                        </div>
                        <ValidationMessage For="() => Input.ConfirmPassword" class="mt-2 text-danger text-sm" />
                    </div>
                    <div>
                        <PrimaryButton type="submit">Set password</PrimaryButton>
                    </div>
                </div>
            </EditForm>
        </div>
    </div>
</div>

@code {
    private string? _message;
    private ApplicationUser _user = default!;

    [SupplyParameterFromForm]
    private InputModel Input { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        Input ??= new();

        _user = await UserAccessor.GetRequiredUserAsync();

        var hasPassword = await UserManager.HasPasswordAsync(_user);
        if (hasPassword)
        {
            RedirectManager.RedirectTo("/Account/Manage/ChangePassword");
            return;
        }
    }

    private async Task OnValidSubmitAsync()
    {
        var addPasswordResult = await UserManager.AddPasswordAsync(_user, Input.NewPassword!);
        if (!addPasswordResult.Succeeded)
        {
            _message = $"Error: {string.Join(",", addPasswordResult.Errors.Select(error => error.Description))}";
            return;
        }

        await SignInManager.RefreshSignInAsync(_user);
        RedirectManager.RedirectToCurrentPageWithStatus("Your password has been set.");
    }

    private sealed class InputModel
    {
        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "New password")]
        public string? NewPassword { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm new password")]
        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
        public string? ConfirmPassword { get; set; }
    }
}
